package com.stars.easyms.logger.support.logback.util;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.spi.AppenderAttachableImpl;
import com.stars.easyms.logger.support.logback.handler.EasyMsAppenderAttachableImpl;
import org.apache.commons.lang3.reflect.FieldUtils;

import java.lang.reflect.Field;
import java.util.List;

/**
 * <p>className: EasyMsLoggerReflectUtil</p>
 * <p>description: logger对象的aai属性转换工具类</p>
 *
 * @author guoguifang
 * @date 2019-08-23 16:23
 * @since 1.3.0
 */
@SuppressWarnings("unchecked")
public final class EasyMsLoggerReflectUtil {

    private static final Field LOGGER_PARENT_FIELD = FieldUtils.getField(Logger.class, "parent", true);

    private static final Field LOGGER_AAI_FIELD = FieldUtils.getField(Logger.class, "aai", true);

    private static final Field AAI_APPENDER_LIST_FIELD = FieldUtils.getField(AppenderAttachableImpl.class, "appenderList", true);

    public static void convertLogger(Logger logger) {
        for (Logger l = logger; l != null; l = getLoggerParent(l)) {
            try {
                AppenderAttachableImpl aai = (AppenderAttachableImpl) LOGGER_AAI_FIELD.get(l);
                if (aai != null && !(aai instanceof EasyMsAppenderAttachableImpl)) {
                    LOGGER_AAI_FIELD.set(l, new EasyMsAppenderAttachableImpl(aai));
                }
            } catch (IllegalAccessException e) {
                // ignore
            }
        }

    }

    public static List<Appender<ILoggingEvent>> getAaiAppenderList(AppenderAttachableImpl aai) {
        try {
            return (List<Appender<ILoggingEvent>>) AAI_APPENDER_LIST_FIELD.get(aai);
        } catch (IllegalAccessException e) {
            return null;
        }
    }

    private static Logger getLoggerParent(Logger logger) {
        try {
            return (Logger) LOGGER_PARENT_FIELD.get(logger);
        } catch (IllegalAccessException e) {
            return null;
        }
    }

    private EasyMsLoggerReflectUtil() {
    }
}